package com.xinxing.learning.security.contoller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@Slf4j
@RestController
public class SecurityContextHolderController {

    @GetMapping("/testSecurityContextHolder")
    public String getSecurityContextHolder() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        User principal = (User) authentication.getPrincipal();
        log.info("认证信息: {}", authentication);
        log.info("身份信息: {}", principal.getUsername());
        log.info("权限信息: {}", authentication.getAuthorities());

        // 模拟子线程中获取上下文的认证信息 默认是MODE_THREADLOCAL模式 无法在子线程中获取上下文中的认证信息
        // 根据org.springframework.security.core.context.SecurityContextHolder#initializeStrategy方法得知
        // 需要设置一个系统变量spring.security.strategy
        // 因此在启动的时候设置一下参数-Dspring.security.strategy=MODE_INHERITABLETHREADLOCAL即可
        new Thread(() -> {
            Authentication subAuthentication = SecurityContextHolder.getContext().getAuthentication();
            // User subPrincipal = (User) subAuthentication.getPrincipal();
            log.info("{}=>认证信息: {}", Thread.currentThread().getName(), subAuthentication);
            // log.info("{}=>身份信息: {}", Thread.currentThread().getName(), subPrincipal.getUsername());
            // log.info("{}=>权限信息: {}", Thread.currentThread().getName(), subAuthentication.getAuthorities());
        }, "SubThread").start();
        return "securityContextHolder test";
    }
}
